<template>
  <div class="rk-form-render-container">
    <v-form-render
      ref="formRenderRef"
      :formJson="formJson"
      :enumsDataConfig="{ dataPools: EnumsDataPools }"
      @formChange="renderFormChange"
      @loadedFormJson="renderFormJsonLoaded"
    >
      <template v-for="item in slotJson" #[item.value]>
        <component
          v-if="RkFormSlotModules.names.includes(item.value)"
          :is="item.value"
          :ref="item.value"
          :busiId="formData.proId"
          :preview="preview"
          :formData="renderFormData"
          :formType="formType"
          :busiType="busiType"
          @setFormItemValue="setFormItemValue"
        >
        </component>
      </template>
    </v-form-render>
  </div>
</template>

<script>
import XEUtils from 'xe-utils'
import RkFormSlotModules from '@/components/form-slots/index.js'
import { computed } from 'vue'
import { EnumsDataPools } from '@/enums/enums-index.js'
import { FormBaseConfigPojo } from './common/rk-form-pojo.js'
import { getPrdFormInfoByFormId } from '@/api/api-form.js'

export default {
  name: 'RkFormRenderBusi',
  components: {
    ...RkFormSlotModules.values
  },
  props: {
    // 表单设计ID，必填
    formId: { type: String, required: true },
    // 是否预览状态
    preview: { type: Boolean, default: false },
    // 表单回显数据
    formData: { type: Object, default: () => ({}) },
    // 表单类型：add|edit|view|yhs
    formType: { type: String, default: 'add' },
    // 附件业务类型
    busiType: { type: String, default: '' }
  },
  watch: {
    formJson: {
      deep: true,
      immediate: false,
      handler(newValue, oldValue) {
        if (!XEUtils.isEmpty(newValue)) {
          const { formRenderRef } = this.$refs
          if (formRenderRef) {
            formRenderRef.setFormJson(newValue)
          }
        }
      },
    },
    formData: {
      deep: true,
      immediate: true,
      handler(newValue, oldValue) {
        this.renderFormData = XEUtils.clone(newValue)
      }
    }
  },
  provide() {
    return {
      dataHouse: computed(() => this.dataHouse)
    }
  },
  data () {
    return {
      loading: false,
      formInfo: {},
      formJson: {},
      slotJson: [],
      dataHouse: {},
      EnumsDataPools,
      RkFormSlotModules,
      renderFormData: {}
    }
  },
  beforeMount() {
    this.loadFormInfo()
  },
  mounted() {
  },
  methods: {
    /**
     * 加载表单信息
     * @param {String} formId 表单设计ID
     */
    async loadFormInfo (formId) {
      this.loading = true
      const formInfo = await this.getRenderFormInfo(this.formId)
      this.formInfo = formInfo
      this.setRenderFormInfo(formInfo)
    },
    /**
     * 获取表单设计信息
     *
     * @param {String} formId 表单ID
     */
    getRenderFormInfo (formId) {
      return new Promise(resolve => {
        getPrdFormInfoByFormId(formId).then(res => {
          const { code, data, msg } = res
          if (code === 200) {
            resolve(data)
          } else {
            console.error(msg)
            resolve({})
          }
        }).catch(err => {
          console.error(err)
          resolve({})
        })
      })
    },
    /** 设置渲染表单信息 */
    setRenderFormInfo (formInfo) {
      let baseFormInfo = {}
      XEUtils.objectEach(FormBaseConfigPojo, (item, key) => {
        baseFormInfo[key] = formInfo[key] || formInfo.prdFormContent[key] || item
      })
      this.formJson = JSON.parse(formInfo.prdFormContent.structureJson)
      this.slotJson = JSON.parse(formInfo.prdFormContent.slotJson)
    },
    /**
     * 表单数据变更触发
     * @param {String} fieldName 修改字段名称
     * @param {Any} newValue 字段修改后的内容
     * @param {Any} oldValue 字段修改前的内容
     * @param {Object} formModel 表单数据
     */
    renderFormChange(fieldName, newValue, oldValue, formModel) {
      const { renderFormData, $refs: { formRenderRef } } = this
      if (formRenderRef && !this.loading) {
        console.log('fieldName', fieldName)
        this.renderFormData = { ...renderFormData, ...formModel }
      }
    },
    /**
     * 表单渲染组件，渲染完成后触发
     */
    renderFormJsonLoaded() {
      this.setRenderFormData()
      this.setRenderFormStatus()
      this.emitLoaded()
    },
    /** 设置表单数据 */
    setRenderFormData() {
      this.$nextTick(() => {
        const { formData, renderFormData} = this
        this.renderFormData = XEUtils.clone(this.formData)
        this.$refs.formRenderRef.setFormData({
          ...renderFormData, ...formData,
        }, true)
      })
    },
    /**
     * 设置单个表单字段的值
     *
     * @param {String} fieldName 表单字段名称
     * @param {String} fieldValue 表单字段内容
     */
    setFormItemValue(fieldName, fieldValue) {
      const { $refs: { formRenderRef } } = this
      formRenderRef.setFieldValue(fieldName, fieldValue)
    },
    /**
     * 设置表单状态
     */
    setRenderFormStatus() {
      const { preview } = this
      this.$nextTick(() => {
        if (preview) {
          this.$refs.formRenderRef.disableForm()
        }
      })
    },
    /**
     * 获取渲染表单数据
     */
    getRenderFormData() {
      return new Promise(reslove => {
        const { renderFormData, slotJson, $refs } = this
        const { formRenderRef } = $refs
        const filedWidgets = formRenderRef.getFieldWidgets()
        const formRenderData = formRenderRef.getFormData(false)
        // console.log("filedWidgets", filedWidgets)
        const finalFormData = { ...renderFormData, ...formRenderData }
        const dataObj = {}
        let dataArray = []
        dataArray = filedWidgets.filter(item => item.type !== 'slot').map(item => {
          const itemObj = {
            guid: item.id,
            code: item.name,
            type: item.type,
            label: item.label,
            value: finalFormData[item.name] || '',
            dataField: item.dataField,
          }
          // 如果是开关组件，就将【true|false】转换为【1|0】
          if (item.type === 'switch') {
            itemObj.value = itemObj.value ? 1 : 0
          }
          dataObj[item.name] = itemObj
          return itemObj
        })
        // 封装插槽数据信息
        let slotsData = {}
        // 遍历插槽
        slotJson.forEach(item => {
          if($refs[item.value]) {
            const { getCompData } = $refs[item.value]
            // 如果获取组件信息的方法不存在，跳过
            if (!getCompData) { return false }
            const compData = $refs[item.value].getCompData()
            slotsData = { ...slotsData, ...compData }
          }
        })
        reslove({
          slotsData, dataArray, dataObj
        })
      })
    },
    validateFormData() {
      const { getFormData, validateForm, getFieldWidgets } = this.$refs.formRenderRef
      let formData = validateForm((valid, invalidFields) => {
        const filedWidgets = getFieldWidgets()
        console.log(valid, invalidFields)
        console.log('filedWidgets', filedWidgets)
        formData = '222'
        return '2222'
      })
      console.log('validateFormData', formData)
    },
    // ----- 以下为emit向上触发事件
    emitLoaded() {
      this.$emit('loaded', this.formInfo)
    },
    emitRenderLoaded() {
      this.$emit('renderLoaded')
    }
  }
}
</script>

<style lang="scss" scoped>
.rk-form-render-container {
  height: 100%;
  :deep(.render-form),
  :deep(.tab-container),
  :deep(.el-tabs),
  :deep(.el-tab-pane) {
    height: 100%;
  }
  :deep(.render-form > .container-wrapper) {
    &:first-child {
      height: 100%;
    }
  }
  :deep(.el-tabs) {
    display: flex;
    flex-direction: column;
  }
  :deep(.el-tabs__header) {
    background-color: #e3f1fe;
    margin-bottom: 0;
  }
  :deep(.el-tabs__nav-scroll) {
    padding: 0 5px;
  }
  :deep(.el-tabs__content) {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 0;
    padding-top: 15px;
  }
  :deep(.el-tab-pane) {
    .upload-main{
      padding: 0;
      position: relative;
      top: -15px;
    }
    // 处理插槽样式
    .slot-widget-item {
      flex: 1;
      min-height: 300px;
      .static-content-item,
      .slot-wrapper-render {
        height: 100%;
      }
    }
  }
}
</style>